<template>
  <div>
    <el-dialog
      width="920px"
      :title="$t('图片上传管理(S)')"
      destroy-on-close
      append-to-body
      :visible.sync="show"
      :before-close="cancel"
    >
      <el-row style="margin-bottom: 10px">
        <el-form :model="queryParams" ref="queryForm" size="small" inline v-show="showSearch">
          <el-form-item prop="originalName">
            <el-input
              :placeholder="$t('原文件名')"
              v-model="queryParams.originalName"
              clearable
              @keyup.enter.native="getList"
            />
          </el-form-item>
          <el-form-item prop="tagIds">
            <el-select
              @change="getList"
              v-model="queryParams.tagIds"
              multiple
              :multiple-limit="4"
              filterable
              clearable
              reserve-keyword
              placeholder="标签名"
            >
              <el-option v-for="item in tags" :key="item.value" :label="item.tagName" :value="item.tagId" />
            </el-select>
          </el-form-item>
          <el-form-item prop="url">
            <el-input :placeholder="$t('URL')" v-model="queryParams.url" clearable @keyup.enter.native="getList" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="getList">
              {{ $t('搜索') }}
            </el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetDialog">
              {{ $t('重置') }}
            </el-button>
          </el-form-item>
        </el-form>
      </el-row>
      <div class="box-main">
        <div class="box-main-left">
          <div
            :key="item.dictValue"
            :class="queryParams.type == item.dictValue ? 'search-selected' : ''"
            v-for="item in ds_oss_type_list"
            @click="
              () => {
                queryParams.type = item.dictValue
                getList()
              }
            "
          >
            {{ item.dictLabel }}
          </div>
        </div>
        <div class="box-main-right">
          <div style="display: flex">
            <el-button
              v-hasPermi="['system:oss:upload']"
              @click="handleUpload"
              type="success"
              icon="el-icon-upload"
              size="mini"
            >
              上传图片
            </el-button>
            <el-button
              v-hasPermi="['system:oss:uploadLink']"
              type="primary"
              icon="el-icon-link"
              style="margin-left: 5px"
              size="mini"
              @click="handleUrl"
            >
              URL链接
            </el-button>
          </div>
          <el-divider content-position="left"><b>近期上传图片</b></el-divider>
          <div class="box-main-right_table">
            <section
              :class="item.checked ? 'img-selected ' : ''"
              class="box-main-right_table__img-wrapper"
              v-for="item in tableData"
              :key="item.id"
            >
              <el-popover :open-delay="400" placement="top-start" width="300" class="img-popover" trigger="hover">
                <el-table :header-cell-style="() => 'background-color: #d7d7d7'" :data="[item]">
                  <el-table-column show-overflow-tooltip width="180" property="originalName" label="原文件名" />
                  <el-table-column show-overflow-tooltip property="fileSuffix" label="文件类型" />
                </el-table>
                <template #reference>
                  <img :src="handleSrc(item)" @click="handleClickImg(item)" />
                  <div class="time">{{ item.createTime }}</div>
                </template>
              </el-popover>
              <div v-if="item.checked" class="selected-icon">
                {{ item.selectIndex }}
              </div>
            </section>

            <div class="box-main-right_table__loading" :style="loading ? 'display:block' : ''">
              <div class="_icon">
                <i class="el-icon-loading"></i>
              </div>
            </div>
          </div>
          <pagination
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
          />
        </div>
      </div>
      <div slot="footer">
        <el-button @click="handleSubmit" type="primary">
          {{ $t('选择图片') }}
        </el-button>
        <el-button @click="cancel">
          {{ $t('关闭') }}
        </el-button>
      </div>
    </el-dialog>
    <!-- ************************************* 外部显示 ***************************************** -->
    <div class="img-list-box" :style="style">
      <draggable
        :disabled="disabled"
        @end="onEnd"
        v-model="outTableData"
        class="img-list-box-draggable"
        chosenClass="chosen"
        forceFallback="true"
        animation="1000"
      >
        <div class="img-item" v-for="(item, index) in outTableData" :key="item.id" @click.stop>
          <img :src="handleSrc(item)" :key="item.id" />
          <div class="img-item-mask">
            <i
              v-if="!disabled && hasPermission"
              class="el-icon-delete delele-icon"
              @click="handleDeleteImg(item, index)"
            ></i>
            <i class="el-icon-view" @click="handlePreview(item)"></i>
          </div>
        </div>
        <!-- 多图添加  防止布局问题 -->
        <div
          class="upload-box"
          @click="hasPermission && (show = true)"
          v-if="outTableData.length < limit && hasPermission && limit > 1 && !disabled"
        >
          <i class="el-icon-plus"></i>
        </div>
      </draggable>
      <!-- 单个图片不用draggable  防止点击不生效 -->
      <div
        class="upload-box"
        @click="hasPermission && (show = true)"
        v-if="outTableData.length < limit && hasPermission && limit == 1 && !disabled"
      >
        <i class="el-icon-plus"></i>
      </div>
    </div>
    <!-- 添加URL链接 -->
    <Url :show.sync="url.show" @getList="getList" />
    <!-- 拖拽上传 -->
    <Upload
      :type="type"
      :businessId="businessId"
      :show.sync="upload.show"
      :uploadLimit="uploadLimit"
      @getList="getList"
    />
  </div>
</template>
<script>
// import { api } from '@/api/**'
import { ossList, ossTagList } from '@/api/distribution/sku/imageSpace'
import { checkPermi } from '@/utils/permission'
import { useDict } from '@/utils/useDict'
import { v4 as uuid } from 'uuid'
import draggable from 'vuedraggable'
import Upload from './upload.vue'
import Url from './url.vue'

export default {
  components: { draggable, Url, Upload },

  props: {
    /**
     * needSplit 是否需要通过 ',' 分割
     */
    needSplit: {
      type: Boolean,
      default: () => true,
    },
    /**
     * disabled 是否禁用
     */
    disabled: {
      type: Boolean,
      default: () => false,
    },
    /**
     * round   round是否圆形
     */
    round: {
      type: Boolean,
      required: false,
    },
    /**
     * wrap    flex-wrap: wrap; 换行显示
     */
    wrap: {
      type: Boolean,
      required: false,
    },
    /**
     * 图片类型
     */
    type: {
      type: String,
      required: true,
    },
    /**
     * permission 权限
     */
    permission: {
      type: String,
    },
    /**
     * 图片列表回显
     */
    fileList: {
      type: String,
      required: true,
    },
    /**
     * 业务id
     */
    businessId: {
      type: [String, Number],
      default: null,
    },
    /**
     * 图片选择数量限制 limit
     */
    limit: {
      type: Number,
      default: 1,
    },
    /**
     * 图片上传数量限制 uploadLimit
     */
    uploadLimit: {
      type: Number,
      default: 1,
    },
  },
  data() {
    return {
      /**选择的总个数 */
      selectTotal: 0,
      upload: { show: false, formData: {} },
      url: { show: false, formData: {} },
      preview: { show: false },
      /**是否正在上传 */
      uploadFlag: false,
      /**待上传列表 */
      waitUploadList: [],
      show: false,
      /**显示搜索条件 */
      showSearch: true,
      tableCheck: [],
      /**表格数据 */
      tableData: [],
      /**表格外数据 */
      outTableData: [],
      tags: [],
      uploadLoading: false,
      loading: false,
      ds_oss_type_list: [],
      /**总条数 */
      total: 0,
      /**分页相关查询参数 */
      queryParams: {
        type: null,
        url: '',
        originalName: '',
        tagIds: [],
        pageNum: 1,
        pageSize: 10,
      },
    }
  },

  mounted() {
    this.handleFileList()
  },

  created() {},
  computed: {
    style() {
      return {
        '--border-radius': this.round ? '50%' : '5px',
        '--flex-wrap': this.wrap ? 'wrap' : 'nowrap',
        '--flex-direction': this.wrap ? 'column' : 'row',
      }
    },
    ImgDisabled() {
      return !(this.tableData.filter((i) => i.checked).length < this.limit)
    },
    tableCheckDisabled() {
      return this.tableCheck.length >= this.limit
    },
    hasPermission() {
      return this.permission ? checkPermi([this.permission]) : true
    },

    canSelectImg() {
      return this.outTableData.length + this.tableData.filter((i) => i.checked).length >= this.limit
    },
  },
  watch: {
    fileList: function (newValue) {
      this.handleFileList()
    },
    show: function (newValue) {
      if (newValue) {
        this.resetDialog()
        this.selectTotal = 0
      }
    },
  },
  methods: {
    handleSrc(item) {
      const urls = item.url.split('?')
      let url = ''
      // 判断是我们的阿里云才添加 缩放参数
      if (item.url.startsWith('http://image-url.cnaget.xyz')) {
        if (urls.length > 1) {
          url = urls[0]
        } else {
          url = item.url + '?x-oss-process=image/resize,w_100/quality,q_70'
        }
        // console.log(`是阿里云 ==>`, url)
      } else {
        url = item.url
        // console.log(`外部链接 ==>`, url)
      }
      return url
    },
    handleUrl() {
      this.url.show = true
    },

    handleUpload(file) {
      this.upload.show = true
    },

    onEnd() {
      const fileList = this.outTableData.filter((i) => i.checked && i.url).map((i) => i.url)
      this.$emit('update:fileList', fileList.toString())
    },

    resetDialog() {
      this.tableData = []
      this.queryParams.tagIds = []
      this.queryParams.pageNum = 1
      this.queryParams.pageSize = 10
      this.queryParams.pageSize = 10
      this.queryParams.url = ''
      this.queryParams.originalName = ''
      this.queryParams.type = null
      // this.queryParams.type = this.type
      this.getList()
      useDict('ds_oss_type', true).then(({ ds_oss_type }) => {
        this.ds_oss_type_list = ds_oss_type
        this.ds_oss_type_list.unshift({ dictLabel: '--全部图片--', dictValue: null })
      })
      ossTagList().then((res) => {
        this.tags = res.rows
      })
    },
    handleFileList() {
      if (!Boolean(this.fileList)) {
        this.outTableData = []
        // this.$emit('update:fileList', '')
      } else {
        if (this.needSplit) {
          this.outTableData = this.fileList.split(',').map((i) => {
            return {
              url: i,
              id: uuid(),
              checked: true,
            }
          })
        } else {
          this.outTableData = [
            {
              url: this.fileList,
              id: uuid(),
              checked: true,
            },
          ]
        }
      }

      // console.log(`this.outTableData  ==>`, JSON.parse(JSON.stringify(this.outTableData)))
    },
    handlePreview(item) {
      // this.preview.formData = item
      // this.preview.show = true
      this.$viewImage(item.url)
    },
    handleDeleteImg(item, idx) {
      this.outTableData.splice(idx, 1)
      const index = this.tableData.findIndex((i) => i.id == item.id)
      if (index !== -1) {
        this.tableData[index].checked = false
      }
      const data = this.outTableData.map((i) => i.url).toString()
      this.$emit('update:fileList', data)
    },
    handleClickImg(item) {
      // 单选直接点击就选择  其他的清空选择
      if (this.limit == 1) {
        this.tableData.forEach((i) => {
          i.checked = false
          i.selectIndex = null
        })
        item.checked = true
        item.selectIndex = 1
        this.selectTotal = 1
        return
      }
      // 选中了的可以取消选中
      if (item.checked) {
        item.checked = false
        this.selectTotal -= 1
        item.selectIndex = null
        const arr = this.tableData.filter((i) => i.checked).sort((a, b) => a.selectIndex - b.selectIndex)
        for (let i = 0; i < this.selectTotal; i++) {
          const index = this.tableData.findIndex((item) => {
            return item.id == arr[i].id
          })
          this.tableData[index].selectIndex = i + 1
        }
        return
      }

      // 判断是否超出图片限制
      if (this.canSelectImg) {
        this.$message({ type: 'error', message: `最多选择${this.limit}张图片!` })
        return
      }
      // 直接选中
      item.checked = true
      this.selectTotal += 1
      item.selectIndex = this.selectTotal
    },

    handleSubmit() {
      const fileList = this.outTableData
        .concat(this.tableData)
        .filter((i) => i.checked && i.url)
        .sort((a, b) => a.selectIndex - b.selectIndex)
        .map((i) => i.url)
      this.$emit('update:fileList', fileList.toString())
      this.$emit('select')
      this.cancel()
    },
    getList() {
      this.loading = true
      this.tableData = []
      ossList(this.queryParams)
        .then((res) => {
          this.tableData = res.rows?.map((i) => {
            return {
              ...i,
              checked: false,
              selectIndex: null,
              id: uuid(),
            }
          })
          this.total = res.total
        })

        .finally(() => (this.loading = false))
    },

    cancel() {
      this.show = false
    },
  },
}
</script>
<style scoped lang="scss">
/*被拖拽对象的样式*/
.item {
  padding: 6px;
  background-color: #fdfdfd;
  border: solid 1px #eee;
  margin-bottom: 10px;
  cursor: move;
}
/*选中样式*/
.chosen {
  //border: solid 2px #3089dc !important;
}
.search-selected {
  background: rgba(70, 166, 255, 0.3);
  font-weight: bold;
}
.img-selected {
  // border: 3px solid #67c23a !important;
}
.box-main {
  display: flex;
  gap: 20px;
  &-left {
    border: 1px solid #ccc;
    border-radius: 3px;
    white-space: nowrap;
    div {
      padding: 10px 25px;
      cursor: pointer;
      white-space: nowrap;
      text-align: center;
      &:hover {
        background: rgba(70, 166, 255, 0.1);
      }
    }
  }
  &-right {
    flex: 1;
    display: flex;
    flex-direction: column;
    &_table {
      position: relative;
      flex: 1;
      max-height: 480px;
      overflow: auto;
      display: flex;
      flex-wrap: wrap;
      gap: 8px;

      &__img-wrapper {
        // border: 1px solid #cccc;
        position: relative;
        display: flex;
        width: 135px;
        height: 155px;
        flex-direction: column;
        overflow: hidden;
        .img-popover {
          height: 100%;
          width: 100%;
          .time {
            font-size: smaller;
            text-align: center;
          }
          img {
            cursor: pointer;
            width: 135px;
            height: 135px;
            object-fit: contain;
            border: 1px solid #cccc;
            border-radius: 3px;
          }
        }

        .selected-icon {
          position: absolute;
          right: 0;
          top: 0;
          font-weight: bold;
          font-size: 20px;
          border-radius: 50%;
          background: #67c23a;
          width: 32px;
          aspect-ratio: 1/1;
          display: flex;
          align-items: center;
          justify-content: center;
          color: white;
        }
      }
      &__loading {
        position: absolute;
        display: none;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.6);
        ._icon {
          width: 100%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 40px;
          color: #ccc;
        }
      }
    }
  }
}

.img-list-box {
  $width: 150px;
  $height: 150px;
  flex-direction: var(--flex-direction);
  display: flex;
  gap: 7px;
  &-draggable {
    display: flex;
    gap: 7px;
    overflow: hidden;
    flex-wrap: var(--flex-wrap);
    .img-item {
      position: relative;
      width: $width;
      height: $height;
      border-radius: var(--border-radius);
      overflow: hidden;
      border: 1px solid #ccc;
      cursor: pointer;

      img {
        width: 100%;
        height: 100%;
        object-fit: contain;
      }
      &:hover {
        .img-item-mask {
          display: flex;
          background-color: rgb(17 24 39 / 0.7);
          color: white;
        }
      }
      &-mask {
        position: absolute;
        left: 50%;
        top: 50%;
        display: none;
        height: 100%;
        width: 100%;
        transform: translate(-50%, -50%);
        align-items: center;
        justify-content: center;
        flex-direction: column;
        gap: 0.25rem;
        line-height: 2rem;
        font-weight: 700;
        font-size: 22px;
        i {
          &:hover {
            transform: scale(1.2);
            color: #409eff;
          }
        }
        .delele-icon {
          position: absolute;
          right: 10px;
          top: 10px;
          &:hover {
            color: red;
          }
        }
      }
    }
  }

  .upload-box {
    width: $width;
    height: $height;
    border-radius: var(--border-radius);
    border: 1px dashed #ccc;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 33px;
    color: #c0c4cc;
    user-select: none;
    &:hover {
      cursor: pointer;
      border-color: #409eff;
      color: #409eff;
    }
  }
}
</style>
